#include "KEY.h"
#include "OS_Event.h"
#include "OS_Timer.h"
#include "OS_TimerUsedTable.h"
#include "Protocol.h"
#include "UserApp.h"
#include "LED.h"
// #include "UserApp.h"
// #include "SC_GPIO.h"
// #include "Function.h"
// #include "TestFunction.h"
// #include "LED.h"
// #include "EEPROM.h"
volatile uint32 rKeyReadBuf;
xdata uint32 RKeyChkBuf,RKeyCvtBuf,RKeyOldBuf;
uint8 cntKeyDebounce;
uint8 RKeyCode;
uint8 CntKeyPress;

xdata uint32 trig_key,trig_state;
xdata uint8 trigIndex,stateIndex;



xdata void(*KeyShortFunc[C_MAX_KEY_NUM+C_MAX_EXT_KEY_NUM])(void) = {  NULL,NULL,NULL,NULL,NULL,
                                                    NULL,NULL,NULL,NULL,NULL,
                                                    NULL,NULL,NULL,NULL,NULL,
                                                    NULL,NULL,NULL,NULL,NULL,
                                                    NULL,NULL,NULL,NULL,NULL,
                                                    NULL,NULL,NULL,NULL,NULL,
                                                    };

xdata void(*KeyLongFunc[C_MAX_KEY_NUM+C_MAX_EXT_KEY_NUM])(void)  = {  NULL,NULL,NULL,NULL,NULL,
                                                    NULL,NULL,NULL,NULL,NULL,
                                                    NULL,NULL,NULL,NULL,NULL,
                                                    NULL,NULL,NULL,NULL,NULL,
                                                    NULL,NULL,NULL,NULL,NULL,
                                                    NULL,NULL,NULL,NULL,NULL,
                                                    };

code uint32 TAB_KEY_CODE[C_MAX_KEY_NUM] = { CODE_KEY1, CODE_KEY2, CODE_KEY3, CODE_KEY4, CODE_KEY5, 
                                            CODE_KEY6, CODE_KEY7, CODE_KEY8, CODE_KEY9, CODE_KEY10,
                                            CODE_KEY11,CODE_KEY12,CODE_KEY13,CODE_KEY14,CODE_KEY15,
                                            CODE_KEY16,CODE_KEY17,CODE_KEY18, CODE_KEY19,CODE_KEY20,
                                            CODE_KEY21,CODE_KEY22,CODE_KEY23, CODE_KEY24,CODE_KEY25,};

void _delay(uint8 time)
{
    while(time--);
}


void initKEY(void)
{
    rKeyReadBuf = 0;
    RKeyChkBuf = 0;
    RKeyCvtBuf = 0;
    RKeyOldBuf = 0;
    cntKeyDebounce = 0;
    RKeyCode = 0;
  
    SET_IN(R1);
    SET_IN(R2);
    SET_IN(R3);
    SET_IN(R4);
    SET_IN(R5);
    SET_IN(L1);
    SET_IN(L2);
    SET_IN(L3); 
    SET_IN(L4); 
    // SET_IN(L5); 
}

void Key_PowerSaveSet(void)
{ 
    SET_OUT(L1,LOW);
    SET_OUT(L2,LOW);
    SET_OUT(L3,LOW);   
    SET_OUT(L4,LOW);
    SET_IN(R1);
    SET_IN(R2);
    SET_IN(R3);
    SET_IN(R4);
    SET_IN(R5);
    // SET_OUT(L5,LOW);

}


//---- ����ƥ�� ----//
uint8 TransBit2Index(uint32 src_dat, uint8 max_idx)
{
    uint8 i;

    for( i = 0; i < max_idx ; i++ )
    {
        if( src_dat == TAB_KEY_CODE[i])
		{
            return i;
        }       
    }

    return INVAILD_KEY;
}

void Key_Read(void)
{
	//-------------------------------------------------------
	//					��	ȡ	��	��
	//-------------------------------------------------------
	SET_IN(R1);
	SET_IN(R2);
	SET_IN(R3);
	SET_IN(R4);
	SET_IN(R5);

    // rKeyReadBuf = TouchKey;
    // rKeyReadBuf = rKeyReadBuf << 20;
    rKeyReadBuf = 0;
    CntKeyPress = 0;
//#if 1
    //---- ɨ���һ�ￄ1�7 ----//
    SET_IN(L5);
    SET_IN(L2);
    SET_IN(L3);
    SET_IN(L4);
    SET_OUT(L1,LOW);
	_delay(20);

    if(GET_PIN(R1) == LOW)  {rKeyReadBuf |= CODE_KEY1; }
    if(GET_PIN(R2) == LOW)  {rKeyReadBuf |= CODE_KEY2; }
    if(GET_PIN(R3) == LOW)  {rKeyReadBuf |= CODE_KEY3; }
    if(GET_PIN(R4) == LOW)  {rKeyReadBuf |= CODE_KEY4; }
    if(GET_PIN(R5) == LOW)  {rKeyReadBuf |= CODE_KEY5; }
    
    //---- ɨ��ڶ��ￄ1�7 ----//
    SET_IN(L1);
    SET_IN(L3);
    SET_IN(L4);
    SET_IN(L5);
    SET_OUT(L2,LOW);
	_delay(20);

    if(GET_PIN(R1) == LOW)  {rKeyReadBuf |= CODE_KEY6; }
    if(GET_PIN(R2) == LOW)  {rKeyReadBuf |= CODE_KEY7; }
    if(GET_PIN(R3) == LOW)  {rKeyReadBuf |= CODE_KEY8; }
    if(GET_PIN(R4) == LOW)  {rKeyReadBuf |= CODE_KEY9; }
    if(GET_PIN(R5) == LOW)  {rKeyReadBuf |= CODE_KEY10;}
    
    //---- ɨ������ￄ1�7 ----//
    SET_IN(L1);
    SET_IN(L2);
    SET_IN(L4);
    SET_IN(L5);
    SET_OUT(L3,LOW);
	_delay(20);
    if(GET_PIN(R1) == LOW)  {rKeyReadBuf |= CODE_KEY11; }
    if(GET_PIN(R2) == LOW)  {rKeyReadBuf |= CODE_KEY12; }
    if(GET_PIN(R3) == LOW)  {rKeyReadBuf |= CODE_KEY13; }
    if(GET_PIN(R4) == LOW)  {rKeyReadBuf |= CODE_KEY14; }
    if(GET_PIN(R5) == LOW)  {rKeyReadBuf |= CODE_KEY15; }
    
    //---- ɨ������ￄ1�7 ----//
    SET_IN(L1);
    SET_IN(L2);
    SET_IN(L3);
    SET_IN(L5);
    SET_OUT(L4,LOW);
	_delay(20);
    if(GET_PIN(R1) == LOW)  {rKeyReadBuf |= CODE_KEY16; }
    if(GET_PIN(R2) == LOW)  {rKeyReadBuf |= CODE_KEY17; }
    if(GET_PIN(R3) == LOW)  {rKeyReadBuf |= CODE_KEY18; }
    if(GET_PIN(R4) == LOW)  {rKeyReadBuf |= CODE_KEY19; }
    if(GET_PIN(R5) == LOW)  {rKeyReadBuf |= CODE_KEY20; }
	_delay(1);

    //---- ɨ������ￄ1�7 ----//
    SET_IN(L1);
    SET_IN(L2);
    SET_IN(L3);
    SET_IN(L4);
    SET_OUT(L5,LOW);
	_delay(20);
    if(GET_PIN(R1) == LOW)  {rKeyReadBuf |= CODE_KEY21; }
    if(GET_PIN(R2) == LOW)  {rKeyReadBuf |= CODE_KEY22; }
    if(GET_PIN(R3) == LOW)  {rKeyReadBuf |= CODE_KEY23; }
    if(GET_PIN(R4) == LOW)  {rKeyReadBuf |= CODE_KEY24; }
    if(GET_PIN(R5) == LOW)  {rKeyReadBuf |= CODE_KEY25; }
	_delay(1);

}

void Key_Main(void)
{
// 	//-------------------------------------------------------
// 	//					��	ȡ	��	��
// 	//-------------------------------------------------------
//     SET_OUT(LED1_COM,LOW);
//     SET_OUT(LED2_COM,LOW);
//     SET_OUT(LED3_COM,LOW);

//     rKeyReadBuf = 0;
//     CntKeyPress = 0;
// #if 1
//     //---- ɨ���һ�ￄ1�7 ----//
//     SET_IN(L2);
//     SET_IN(L3);
//     SET_IN(L4);
//     // SET_IN(L5);
//     SET_OUT(L1,LOW);
// 	_delay(100);

//     if(GET_PIN(R1) == LOW)  {rKeyReadBuf |= CODE_KEY1; CntKeyPress++;}
//     if(GET_PIN(R2) == LOW)  {rKeyReadBuf |= CODE_KEY2; CntKeyPress++;}
//     if(GET_PIN(R3) == LOW)  {rKeyReadBuf |= CODE_KEY3; CntKeyPress++;}
//     if(GET_PIN(R4) == LOW)  {rKeyReadBuf |= CODE_KEY4; CntKeyPress++;}
//     if(GET_PIN(R5) == LOW)  {rKeyReadBuf |= CODE_KEY5; CntKeyPress++;}
    
//     //---- ɨ��ڶ��ￄ1�7 ----//
//     #if _DEBUG_EN_ == 0
//     SET_IN(L1);
//     SET_IN(L3);
//     SET_IN(L4);
//     // SET_IN(L5);
//     SET_OUT(L2,LOW);
// 	_delay(100);

//     if(GET_PIN(R1) == LOW)  {rKeyReadBuf |= CODE_KEY6; CntKeyPress++;}
//     if(GET_PIN(R2) == LOW)  {rKeyReadBuf |= CODE_KEY7; CntKeyPress++;}
//     if(GET_PIN(R3) == LOW)  {rKeyReadBuf |= CODE_KEY8; CntKeyPress++;}
//     if(GET_PIN(R4) == LOW)  {rKeyReadBuf |= CODE_KEY9; CntKeyPress++;}
//     if(GET_PIN(R5) == LOW)  {rKeyReadBuf |= CODE_KEY10;CntKeyPress++;}
//     #endif
    
//     //---- ɨ������ￄ1�7 ----//
//     SET_IN(L1);
//     SET_IN(L2);
//     SET_IN(L4);
//     // SET_IN(L5);
//     SET_OUT(L3,LOW);
// 	_delay(100);
//     if(GET_PIN(R1) == LOW)  {rKeyReadBuf |= CODE_KEY11; CntKeyPress++;}
//     if(GET_PIN(R2) == LOW)  {rKeyReadBuf |= CODE_KEY12; CntKeyPress++;}
//     if(GET_PIN(R3) == LOW)  {rKeyReadBuf |= CODE_KEY13; CntKeyPress++;}
//     if(GET_PIN(R4) == LOW)  {rKeyReadBuf |= CODE_KEY14; CntKeyPress++;}
//     if(GET_PIN(R5) == LOW)  {rKeyReadBuf |= CODE_KEY15; CntKeyPress++;}
    
//     //---- ɨ������ￄ1�7 ----//
//     SET_IN(L1);
//     SET_IN(L2);
//     SET_IN(L3);
//     // SET_IN(L5);
//     SET_OUT(L4,LOW);
// 	_delay(100);
//     if(GET_PIN(R1) == LOW)  {rKeyReadBuf |= CODE_KEY16; CntKeyPress++;}
//     if(GET_PIN(R2) == LOW)  {rKeyReadBuf |= CODE_KEY17; CntKeyPress++;}
//     if(GET_PIN(R3) == LOW)  {rKeyReadBuf |= CODE_KEY18; CntKeyPress++;}
//     if(GET_PIN(R4) == LOW)  {rKeyReadBuf |= CODE_KEY19; CntKeyPress++;}
//     if(GET_PIN(R5) == LOW)  {rKeyReadBuf |= CODE_KEY20; CntKeyPress++;}
    
    //---- ɨ������ￄ1�7 ----//
//    SET_IN(L1);
//    SET_IN(L2);
//    SET_IN(L3);
//    SET_IN(L4);
//    SET_OUT(L5,LOW);
//	_delay(100);
//    if(GET_PIN(R1) == LOW)  {rKeyReadBuf |= CODE_KEY21; CntKeyPress++;}
//    if(GET_PIN(R2) == LOW)  {rKeyReadBuf |= CODE_KEY22; CntKeyPress++;}
//    if(GET_PIN(R3) == LOW)  {rKeyReadBuf |= CODE_KEY23; CntKeyPress++;}
//    if(GET_PIN(R4) == LOW)  {rKeyReadBuf |= CODE_KEY24; CntKeyPress++;}
//    if(GET_PIN(R5) == LOW)  {rKeyReadBuf |= CODE_KEY25; CntKeyPress++;}

    //-------------------------------------------------------
    //              �� �� �� ��
    //-------------------------------------------------------   
    if(rKeyReadBuf != RKeyChkBuf)
    {
        RKeyChkBuf = rKeyReadBuf;
        cntKeyDebounce = 0;
    }
    else
    {
        if(cntKeyDebounce++ >= TM_DBC_KEY)
        {
            cntKeyDebounce = 0;
            RKeyCvtBuf = RKeyChkBuf;
        }
    }
    
    //-------------------------------------------------------
    //              �� �� ʶ ��
    //-------------------------------------------------------
    if(RKeyCvtBuf != RKeyOldBuf)
    {
        trig_key = RKeyOldBuf^RKeyCvtBuf;       // ��ȡ�����仯λ
        trig_state = trig_key & RKeyCvtBuf;

        RKeyOldBuf = RKeyCvtBuf;

        trigIndex = TransBit2Index( trig_key, C_MAX_KEY_NUM );     //  �õ�����״̬�仯����
        stateIndex= TransBit2Index( trig_state, C_MAX_KEY_NUM );   //  �õ�����״̬����

        if( trigIndex == stateIndex )
        {
        //---- ��ￄ1�7 ���ж�Ӧ�������� ----//
            RKeyCode = stateIndex;
            if( CntKeyPress > C_MAX_KEY_PRESS )   RKeyCode = INVAILD_KEY;    //  ���ư�����ￄ1�7 2 ��

            if( RKeyCode != INVAILD_KEY )
            {
                //---- ��Ч���� ----//
                OS_SetEvent(OS_EVENT_ANY_KEY_CHANGE);
                // if((RKeyCode == CODE_COMBO_K1)||(RKeyCode == CODE_COMBO_K2))
                // {
                //     if( TmDelayPowerOn )
                //         TmDelayPowerOn = 30;
                // }
            }
            else
            {
                //---- ��Ч���� ----//
                OS_StopTimer(TIMER_KEY);
                OS_ClrEvent(OS_EVENT_ANY_KEY_CHANGE);
            }
        }
        else
        {
        //---- ���� ���Ӧ�����ͷￄ1�7 ----//
            if( RKeyCode == trigIndex )
            {
                OS_ClrEvent(OS_EVENT_ANY_KEY_CHANGE);
                OS_SetEvent(OS_EVENT_ALL_KEY_RELEASE);
            }
            else
            {
                OS_StopTimer(TIMER_KEY);
            }
        }
    }

}



void    FCB_KeyXLongPress(void)
{
    OS_StopTimer(TIMER_KEY);
    OS_SetEvent(OS_EVENT_LONG_PRESS);
    
}

#if 1
uint8 CalcNumOfKeyPress(uint32 key_code)
{
    uint8 i;
    uint8 sum_key = 0;

    for(i=0; i<C_MAX_KEY_NUM; i++)
    {
        if(key_code & 0x00000001ul)
            sum_key++;
        key_code = key_code >> 1;
    }
    return sum_key;
}

void    ComboKey_Check(void)
{
    //---- 组合键判断 ----//
    if((RKeyOldBuf != TAB_KEY_CODE[RKeyCode]) && ((RKeyOldBuf & ~(CODE_KEY_COMBO1_OFFSET|CODE_KEY_COMBO2_OFFSET|CODE_KEY_COMBO3_OFFSET|CODE_KEY_COMBO4_OFFSET|CODE_KEY_COMBO5_OFFSET))== CODE_KEY_COMBO_BASE))
    {
        if(RKeyCode == KEY_CHONGSHUI)
        {
            RKeyCode = C_MAX_KEY_NUM + KEY_COMBO1_OFFSET;
        }
        else if(RKeyCode == KEY_PAOMODUN)
        {
            RKeyCode = C_MAX_KEY_NUM + KEY_COMBO2_OFFSET;
        }
        else if(RKeyCode == KEY_FANGAI)
        {
            RKeyCode = C_MAX_KEY_NUM + KEY_COMBO3_OFFSET;

        }
        else if(RKeyCode == KEY_FANQUAN)
        {
            RKeyCode = C_MAX_KEY_NUM + KEY_COMBO4_OFFSET;

        }
        else if(RKeyCode == KEY_YEDENG)
        {
            RKeyCode = C_MAX_KEY_NUM + KEY_COMBO5_OFFSET;

        }
        else
        {
            RKeyCode = INVAILD_KEY;
        }
    }
    else if(CalcNumOfKeyPress(RKeyOldBuf) >= 2)
    {
        RKeyCode = INVAILD_KEY;
    }
    //-------------------//
}
#endif

void    MultiKey_Proc(void)
{
    if(OS_GetEvent(OS_EVENT_LONG_PRESS))
    {
        OS_ClrEvent(OS_EVENT_LONG_PRESS);

        ComboKey_Check();
        
        if(KeyLongFunc[RKeyCode])
        {
		  if(CheckWkMode(WM_PAIR))
            ExitPairSetting();
          else
            SwitchWkMode(WM_NORMAL);
          ResetTimeSleep();
          KeyLongFunc[RKeyCode]();
        }
    }
    
    if(OS_GetEvent(OS_EVENT_ANY_KEY_CHANGE))
    {
        OS_ClrEvent(OS_EVENT_ANY_KEY_CHANGE);
        OS_StartTimer(TIMER_KEY, TIMER_2S, FCB_KeyXLongPress);
        // SendCommand(RKeyCode);
    }

    if(OS_GetEvent(OS_EVENT_ALL_KEY_RELEASE))
    {
        OS_ClrEvent(OS_EVENT_ALL_KEY_RELEASE);
  
        if(OS_CheckTimerState(TIMER_KEY))
        {
            OS_StopTimer(TIMER_KEY);

            ComboKey_Check();

            //---- ����ģʽ ----//
            if(KeyShortFunc[RKeyCode])
            {
		        if(CheckWkMode(WM_PAIR))
					ExitPairSetting();
                else
                    SwitchWkMode(WM_NORMAL);
                ResetTimeSleep();
                KeyShortFunc[RKeyCode]();
            }
        }
    }

}


